﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using NetMicro.Core.ConfigureOptions;
using NetMicro.Core.DynamicWebApiController.Conventions;
using NetMicro.Core.DynamicWebApiController.Options;
using NetMicro.Core.DynamicWebApiController.Providers;
using NetMicro.Core.Helper;
using NetMicro.Core.Ioc.Attributes;
using NetMicro.Webs.DynamicWebApiController.Options;
using Penetrates = NetMicro.Core.DynamicWebApiController.Internal.Penetrates;

namespace NetMicro.Core.DynamicWebApiController.Extensions
{
    /// <summary>
    ///动态接口控制器拓展类
    /// </summary>
    [SkipScan]
    public static class ServiceCollectionExtensions
    {

        /// <summary>
        /// 添加动态接口控制器服务
        /// </summary>
        /// <param name="mvcBuilder">Mvc构建器</param>
        /// <returns>Mvc构建器</returns>
        public static IMvcBuilder AddDynamicApiControllersAsServices(this IMvcBuilder mvcBuilder)
        {
            mvcBuilder.AddControllersAsServices();
            var type = App.Assemblies.SelectMany(m => m.GetTypes()).Where(t => Penetrates.IsApiController(t)).ToList();
            type.ForEach(m =>
            {
                mvcBuilder.Services.AddTransient(m);
            });
            return mvcBuilder;
        }

        /// <summary>
        /// 添加动态接口控制器服务
        /// </summary>
        /// <param name="mvcBuilder">Mvc构建器</param>
        /// <returns>Mvc构建器</returns>
        public static IMvcBuilder AddDynamicApiControllers(this IMvcBuilder mvcBuilder)
        {
            mvcBuilder.Services.AddConfigure<ModuleSettingsOptions>();
            mvcBuilder.Services.AddDynamicApiControllers();
            return mvcBuilder;
        }

        /// <summary>
        /// 添加动态接口控制器服务
        /// </summary>
        /// <param name="services"></param>
        /// <returns>Mvc构建器</returns>
        public static IServiceCollection AddDynamicApiControllers(this IServiceCollection services)
        {
            ApplicationPartManager partManager = services.FirstOrDefault(s => s.ServiceType == typeof(ApplicationPartManager))?.ImplementationInstance as ApplicationPartManager
                ?? throw new InvalidOperationException($"`{nameof(AddDynamicApiControllers)}` must be invoked after `{nameof(MvcServiceCollectionExtensions.AddControllers)}`.");

            // 载入模块化/插件程序集部件
            if (App.ExternalAssemblies.Any())
            {
                foreach (Assembly assembly in App.ExternalAssemblies)
                {
                    partManager.ApplicationParts.Add(new AssemblyPart(assembly));
                }
            }

            // 添加控制器特性提供器
            partManager.FeatureProviders.Add(new DynamicWebApiControllerFeatureProvider());

            // 添加配置
            services.AddConfigure<DynamicWebApiControllerSettingsOptions>();

            // 配置 Mvc 选项
            services.Configure<MvcOptions>(options =>
            {
                // 添加应用模型转换器
                options.Conventions.Add(new DynamicWebApiControllerApplicationModelConvention());
            });

            return services;
        }

        /// <summary>
        /// 添加外部程序集部件集合
        /// </summary>
        /// <param name="mvcBuilder">Mvc构建器</param>
        /// <param name="assemblies"></param>
        /// <returns>Mvc构建器</returns>
        public static IMvcBuilder AddExternalAssemblyParts(this IMvcBuilder mvcBuilder, IEnumerable<Assembly> assemblies)
        {
            // 载入程序集部件
            if (assemblies != null && assemblies.Any())
            {
                foreach (Assembly assembly in assemblies)
                {
                    mvcBuilder.AddApplicationPart(assembly);
                }
            }

            return mvcBuilder;
        }
    }
}